//singleton
// $Id: singleton.h 269 2009-11-18 18:27:25Z Oleg.Bulychov $
#pragma once

//:T must be: no-throw default constructible and no-throw destructible
//:WARINIG: is not thread-safe!

template<class T>
struct singleton_holder
{
    T t_;
#if defined(_DEBUG)
    static volatile long destroyed_;

    ~singleton_holder() NO_THROW_()
    {
        ++destroyed_;
    }
#endif
};
#if defined(_DEBUG)
template<class T>
volatile long singleton_holder<T>::destroyed_ = 0;
#endif

template<class T>
class singleton
{
    static ATTRIBUTE_EXPORT T& instance_;
    static void instantiate(T&) NO_THROW_()
    {}
public:
    typedef T value_type;
    typedef singleton<T> TSingleton;

    static T& instance() NO_THROW_() ATTRIBUTE_USED
    {
        static singleton_holder<T> sh;
#if defined(_DEBUG)
        ASSERT_(!sh.destroyed_);//:dead can dance
#endif
        instantiate(instance_);
        return sh.t_;
    }
};

template<class T>
ATTRIBUTE_EXPORT T& singleton<T>::instance_ = singleton<T>::instance();

//_______________________________________________________________________________________________
//_______________________________________________________________________________________________
//_______________________________________________________________________________________________
//_______________________________________________________________________________________________
//_______________________________________________________________________________________________
//_______________________________________________________________________________________________

//EOF!
